<template>
  <div class="side-bar" :class="sideBarCls" :style="stlyVariable">
    <header class="side-bar__header">
      <transition name="fade">
        <slot name="header-title" v-if="sideBarshow" />
      </transition>
      <span class="iconfont icon-daohanglan" @click="toggleSideBar"></span>
    </header>
    <slot />
  </div>
</template>

<script>
import SideBarItem from './side_bar_item.vue'
import { throttle } from '/src/util/throttle.js'
const INTERVAL = 400

export default {
  components: {
    SideBarItem
  },

  data() {
    return {
      sideBarshow: false,
      initStatus: true // 用来标记是不是最开始的状态，最开始的时候默认不显示动画
    }
  },

  watch: {
    '$store.state.devType': {
      deep: true,
      immediate: true,
      handler(v) {
        if (['pad', 'mobile'].includes(v) && this.initStatus) {
          this.toggleSideBar()
        }
      }
    }
  },

  computed: {
    sideBarCls() {
      // 最开始刚进来的时候，菜单栏应该是没有切换效果的
      if (this.initStatus) {
        return ''
      }

      return `side-bar--${this.sideBarshow ? 'open' : 'fold'}`
    },

    stlyVariable() {
      let {
        minSideBarWidth,
        maxSideBarWidth,
        sideBarAnimationTime
      } = this.$store.state

      return {
        '--maxSideBarWidth': maxSideBarWidth,
        '--minSideBarWidth': minSideBarWidth,
        '--sideBarAnimationTime': sideBarAnimationTime
      }
    }
  },

  mounted() {
    this.init()
  },

  methods: {
    init() {
      this.loadInitToggleStatus()

      this.$nextTick(() => {
        if (this.$store.state.devType === 'mobile') {
          window.addEventListener(
            'click',
            throttle(this.judgeUserClickOutside, INTERVAL),
            true
          )
        }
      })
    },

    loadInitToggleStatus() {
      this.sideBarshow = this.$store.state.foldMenu
    },

    toggleSideBar() {
      this.initStatus = false
      this.$store.commit('updateMenuStatus', !this.sideBarshow)
      this.sideBarshow = !this.sideBarshow
    },

    judgeUserClickOutside(event) {
      let container = document.getElementsByClassName('side-bar')[0]

      // 如果展开来了，但是这个时候点击了外面，那就要隐藏菜单栏
      if (this.sideBarshow && !container?.contains(event.target)) {
        this.toggleSideBar()
      }
    }
  },

  beforeDestroy() {
    if (this.$store.state.devType === 'mobile') {
      window.removeEventListener('click', this.judgeUserClickOutside, true)
    }
  }
}
</script>

<style scoped>
.side-bar {
  position: fixed;
  top: 0;
  bottom: 0;
  z-index: 1000;
  padding: 30px;
  width: var(--maxSideBarWidth);
  box-sizing: border-box;
  background-color: #fff;
  border-right: 1px solid #ddd;
}

.side-bar__header {
  overflow: hidden;
  position: relative;
  margin-bottom: 50px;
  height: 17px;
  white-space: nowrap;
  overflow: hidden;
}

.side-bar__header .iconfont {
  float: right;
  margin-right: 5px;
  text-align: center;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}

/* 展开的动画 */
.side-bar--open {
  width: var(--minSideBarWidth);
  animation: open-animation var(--sideBarAnimationTime) forwards;
}
@keyframes open-animation {
  0% {
    width: var(--minSideBarWidth);
  }
  100% {
    width: var(--maxSideBarWidth);
  }
}

/* 收起来的动画 */
.side-bar--fold {
  width: var(--maxSideBarWidth);
  animation: fold-animation var(--sideBarAnimationTime) forwards;
}
@keyframes fold-animation {
  0% {
    width: var(--maxSideBarWidth);
  }
  100% {
    width: var(--minSideBarWidth);
  }
}

/* 手机的折叠与展开动画有点不一样 */
@media (max-width: 768px) {
  /* 移动端这里不显示icon */
  .side-bar .icon-daohanglan {
    display: none;
  }

  @keyframes open-animation {
    0% {
      width: var(--minSideBarWidth);
      padding: 30px 0;
    }
    100% {
      width: var(--maxSideBarWidth);
      padding: 30px;
    }
  }

  @keyframes fold-animation {
    0% {
      width: var(--maxSideBarWidth);
      padding: 30px;
    }
    100% {
      width: var(--minSideBarWidth);
      padding: 30px 0;
    }
  }
}
</style>